home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / borcmpad / mpfile.c < prev    next >
C/C++ Source or Header  |  1991-07-23  |  16KB  |  476 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  MODULE    : MpFile.c                                                   *
  4.  *                                                                         *
  5.  *  PURPOSE   : Contains the code for File I/O for Multipad.               *
  6.  *                                                                         *
  7.  *  FUNCTIONS : AlreadyOpen   - Determines if a file is already open.      *
  8.  *                                                                         *
  9.  *              AddFile       - Creates a new MDI window and, if specified,*
  10.  *                loads a file into it.                      *
  11.  *                                                                         *
  12.  *              LoadFile      - Loads a file into a MDI window.            *
  13.  *                                                                         *
  14.  *              ReadFile      - Calls File/Open dialog and appropriately   *
  15.  *                              responds to the user's input.              *
  16.  *                                                                         *
  17.  *              SaveFile      - Saves the contents of a MDI window's edit  *
  18.  *                              control to a file.                         *
  19.  *                                                                         *
  20.  *              SetSaveFrom   - Formats the "Save 'file' to" string.       *
  21.  *                                                                         *
  22.  *              SaveAsDlgProc - Dialog function for the File/SaveAs dialog.*
  23.  *                                                                         *
  24.  *              ChangeFile    - Calls File/SaveAs dialog.                  *
  25.  *                                                                         *
  26.  ***************************************************************************/
  27. #include "multipad.h"
  28.  
  29. VOID NEAR PASCAL GetFileName(PSTR);
  30. int FAR PASCAL DialogBoxParam(HANDLE,LPSTR,HWND,FARPROC,LONG);
  31.  
  32. OFSTRUCT    of;
  33. /****************************************************************************
  34.  *                                                                          *
  35.  *  FUNCTION   : AlreadyOpen(szFile)                                        *
  36.  *                                                                          *
  37.  *  PURPOSE    : Checks to see if the file described by the string pointed  *
  38.  *               to by 'szFile' is already open.                            *
  39.  *                                                                          *
  40.  *  RETURNS    : a handle to the described file's window if that file is    *
  41.  *               already open;  NULL otherwise.                             *
  42.  *                                                                          *
  43.  ****************************************************************************/
  44.  
  45. HWND AlreadyOpen(char *szFile)
  46. {
  47.     int     iDiff;
  48.     HWND    hwndCheck;
  49.     char    szChild[64];
  50.     LPSTR   lpChild, lpFile;
  51.     int     wFileTemp;
  52.  
  53.     /* Open the file with the OF_PARSE flag to obtain the fully qualified
  54.      * pathname in the OFSTRUCT structure.
  55.      */
  56.     wFileTemp = OpenFile ((LPSTR)szFile, (LPOFSTRUCT)&of, OF_PARSE);
  57.     if (! wFileTemp)
  58.     return(NULL);
  59.     _lclose (wFileTemp);
  60.  
  61.     /* Check each MDI child window in Multipad */
  62.     for (   hwndCheck = GetWindow(hwndMDIClient, GW_CHILD);
  63.         hwndCheck;
  64.         hwndCheck = GetWindow(hwndCheck, GW_HWNDNEXT)   ) {
  65.     /* Initialization  for comparison */
  66.     lpChild = szChild;
  67.     lpFile = AnsiUpper((LPSTR) of.szPathName);
  68.     iDiff = 0;
  69.  
  70.     /* Skip icon title windows */
  71.     if (GetWindow(hwndCheck, GW_OWNER))
  72.         continue;
  73.  
  74.     /* Get current child window's name */
  75.     GetWindowText(hwndCheck, lpChild, 64);
  76.  
  77.     /* Compare window name with given name */
  78.     while ((*lpChild) && (*lpFile) && (!iDiff)){
  79.         if (*lpChild++ != *lpFile++)
  80.         iDiff = 1;
  81.     }
  82.  
  83.     /* If the two names matched, the file is already   */
  84.     /* open -- return handle to matching child window. */
  85.     if (!iDiff)
  86.         return(hwndCheck);
  87.     }
  88.     /* No match found -- file is not open -- return NULL handle */
  89.     return(NULL);
  90. }
  91.  
  92. /****************************************************************************
  93.  *                                        *
  94.  *  FUNCTION   : AddFile (lpName)                        *
  95.  *                                        *
  96.  *  PURPOSE    : Creates a new MDI window. If the lpName parameter is not   *
  97.  *         NULL, it loads a file into the window.             *
  98.  *                                        *
  99.  *  RETURNS    : HWND  - A handle to the new window.                *
  100.  *                                        *
  101.  ****************************************************************************/
  102.  
  103. HWND FAR PASCAL AddFile(pName)
  104. char * pName;
  105. {
  106.     HWND hwnd;
  107.  
  108.     char        sz[160];
  109.     MDICREATESTRUCT mcs;
  110.  
  111.     if (!pName) {
  112.     /* The pName parameter is NULL -- load the "Untitled" string from */
  113.     /* STRINGTABLE and set the title field of the MDI CreateStruct.    */
  114.     LoadString (hInst, IDS_UNTITLED, sz, sizeof(sz));
  115.     mcs.szTitle = (LPSTR)sz;
  116.     }
  117.     else
  118.     /* Title the window with the fully qualified pathname obtained by
  119.      * calling OpenFile() with the OF_PARSE flag (in function
  120.      * AlreadyOpen(), which is called before AddFile().
  121.      */
  122.     mcs.szTitle = of.szPathName;
  123.  
  124.     mcs.szClass = szChild;
  125.     mcs.hOwner    = hInst;
  126.  
  127.     /* Use the default size for the window */
  128.     mcs.x = mcs.cx = CW_USEDEFAULT;
  129.     mcs.y = mcs.cy = CW_USEDEFAULT;
  130.  
  131.     /* Set the style DWORD of the window to default */
  132.     mcs.style = styleDefault;
  133.  
  134.     /* tell the MDI Client to create the child */
  135.     hwnd = (WORD)SendMessage (hwndMDIClient,
  136.                   WM_MDICREATE,
  137.                   0,
  138.                   (LONG)(LPMDICREATESTRUCT)&mcs);
  139.  
  140.     /* Did we get a file? Read it into the window */
  141.     if (pName){
  142.     if (!LoadFile(hwnd, pName)){
  143.         /* File couldn't be loaded -- close window */
  144.         SendMessage(hwndMDIClient, WM_MDIDESTROY, (WORD) hwnd, 0L);
  145.     }
  146.     }
  147.  
  148.     return hwnd;
  149. }
  150.  
  151. /****************************************************************************
  152.  *                                        *
  153.  *  FUNCTION   : LoadFile (lpName)                        *
  154.  *                                        *
  155.  *  PURPOSE    : Given the handle to a MDI window and a filename, reads the *
  156.  *         file into the window's edit control child.                 *
  157.  *                                        *
  158.  *  RETURNS    : TRUE  - If file is sucessfully loaded.             *
  159.  *         FALSE - Otherwise.                        *
  160.  *                                        *
  161.  ****************************************************************************/
  162.  
  163. int FAR PASCAL LoadFile (hwnd, pName)
  164. HWND hwnd;
  165. char * pName;
  166. {
  167.     WORD   wLength;
  168.     HANDLE hT;
  169.     LPSTR  lpB;
  170.     HWND   hwndEdit;
  171.     int    fh;
  172.  
  173.     hwndEdit = GetWindowWord (hwnd, GWW_HWNDEDIT);
  174.  
  175.     /* The file has a title, so reset the UNTITLED flag. */
  176.     SetWindowWord(hwnd, GWW_UNTITLED, FALSE);
  177.  
  178.     fh = _lopen (pName, 0);
  179.  
  180.     /* Make sure file has been opened correctly */
  181.     if ( fh < 0 )
  182.     goto error;
  183.  
  184.     /* Find the length of the file */
  185.     wLength = (WORD)_llseek (fh, 0L, 2);
  186.     _llseek (fh, 0L, 0);
  187.  
  188.     /* Attempt to reallocate the edit control's buffer to the file size */
  189.     hT = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  190.     if (LocalReAlloc(hT, wLength+1, LHND) == NULL) {
  191.     /* Couldn't reallocate to new size -- error */
  192.     _lclose (fh);
  193.     goto error;
  194.     }
  195.  
  196.     /* read the file into the buffer */
  197.     if (wLength != _lread (fh, (lpB = (LPSTR)LocalLock (hT)), wLength))
  198.     MPError (hwnd, MB_OK|MB_ICONHAND, IDS_CANTREAD, (LPSTR)pName);
  199.  
  200.     /* Zero terminate the edit buffer */
  201.     lpB[wLength] = 0;
  202.     LocalUnlock (hT);
  203.  
  204.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  205.     _lclose (fh);
  206.  
  207.     return TRUE;
  208.  
  209. error:
  210.     /* Report the error and quit */
  211.     MPError(hwnd, MB_OK | MB_ICONHAND, IDS_CANTOPEN, (LPSTR)pName);
  212.     return FALSE;
  213. }
  214.  
  215. /****************************************************************************
  216.  *                                                                          *
  217.  *  FUNCTION   : ReadFile(hwnd)                                             *
  218.  *                                                                          *
  219.  *  PURPOSE    : Called in response to a File/Open menu selection. It asks  *
  220.  *               the user for a file name and responds appropriately.       *
  221.  *                                                                          *
  222.  ****************************************************************************/
  223.  
  224. VOID FAR PASCAL ReadFile(HWND hwnd)
  225. {
  226.     char    szFile[128];
  227.     HWND    hwndFile;
  228.  
  229.     GetFileName (szFile);
  230.  
  231.     /* If the result is not the empty string -- take appropriate action */
  232.     if (*szFile) {
  233.     /* Is file already open?? */
  234.     if ((hwndFile = AlreadyOpen(szFile)) != (HWND)0) {
  235.         /* Yes -- bring the file's window to the top */
  236.         BringWindowToTop(hwndFile);
  237.     }
  238.     else {
  239.         /* No -- make a new window and load file into it */
  240.         AddFile(szFile);
  241.     }
  242.     }
  243. }
  244.  
  245. /****************************************************************************
  246.  *                                        *
  247.  *  FUNCTION   : SaveFile (hwnd)                        *
  248.  *                                        *
  249.  *  PURPOSE    : Saves contents of current edit control to disk.        *
  250.  *                                        *
  251.  ****************************************************************************/
  252.  
  253. VOID FAR PASCAL SaveFile( hwnd )
  254.  
  255. HWND hwnd;
  256. {
  257.     HANDLE   hT;
  258.     LPSTR    lpT;
  259.     char     szFile[128];
  260.     WORD     cch;
  261.     int      fh;
  262.     OFSTRUCT of;
  263.     HWND     hwndEdit;
  264.  
  265.     hwndEdit = GetWindowWord ( hwnd, GWW_HWNDEDIT);
  266.     GetWindowText (hwnd, szFile, sizeof(szFile));
  267.  
  268.     /* If there is no extension (control is 'Untitled') add .TXT as extension */
  269.     for (cch = FALSE, lpT = szFile; *lpT; lpT++)
  270.     switch (*lpT){
  271.         case '.':
  272.          cch = TRUE;
  273.          break;
  274.  
  275.         case '\\':
  276.         case ':' :
  277.          cch = FALSE;
  278.          break;
  279.     }
  280.     if (!cch)
  281.     LoadString (hInst, IDS_ADDEXT, lpT, (unsigned)(lpT - (LPSTR)szFile));
  282.  
  283.     fh = OpenFile (szFile, &of, OF_WRITE | OF_CREATE);
  284.  
  285.     /* If file could not be opened, quit */
  286.     if (fh < 0){
  287.     MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTCREATE, (LPSTR)szFile);
  288.     return;
  289.     }
  290.  
  291.     /* Find out the length of the text in the edit control */
  292.     cch = GetWindowTextLength (hwndEdit);
  293.  
  294.     /* Obtain a handle to the text buffer */
  295.     hT    = (HANDLE)SendMessage (hwndEdit, EM_GETHANDLE, 0, 0L);
  296.     lpT = (LPSTR)LocalLock (hT);
  297.  
  298.     /* Write out the contents of the buffer to the file. */
  299.     if (cch != _lwrite (fh, lpT, cch))
  300.     MPError (hwnd, MB_OK | MB_ICONHAND, IDS_CANTWRITE, (LPSTR)szFile);
  301.  
  302.     /* Clean up */
  303.     LocalUnlock (hT);
  304.     SendMessage (hwndEdit, EM_SETHANDLE, hT, 0L);
  305.  
  306.     _lclose (fh);
  307.  
  308.     return;
  309. }
  310.  
  311. /****************************************************************************
  312.  *                                        *
  313.  *  FUNCTION   : SetSaveFrom ()                         *
  314.  *                                        *
  315.  *  PURPOSE    : Formats the "Save 'file' to .." string.            *
  316.  *                                        *
  317.  ****************************************************************************/
  318.  
  319. VOID NEAR PASCAL SetSaveFrom ( hwnd , psz)
  320. HWND hwnd;
  321. PSTR psz;
  322. {
  323.     char szFmt[32];
  324.     char szText[160];
  325.  
  326.     /* The text string in the .RC file contains the format string... */
  327.     GetDlgItemText( hwnd, IDD_SAVEFROM, szFmt, sizeof(szFmt));
  328.  
  329.     /* NOTE: this (LPSTR) cast MUST be here... wsprintf() is a cdecl
  330.      * (C calling conventions) function with varying args... there is
  331.      * no way for the compiler to know that all strings must be LPSTR's
  332.      * and do the conversion, so we have to be careful about wsprintf()'s.
  333.      */
  334.     wsprintf ( szText, szFmt, (LPSTR)psz);
  335.  
  336.     /* set the text in the static control */
  337.     SetDlgItemText (hwnd, IDD_SAVEFROM, szText);
  338. }
  339.  
  340. /****************************************************************************
  341.  *                                        *
  342.  *  FUNCTION   : SaveAsDlgProc(hwnd, message, wParam, lParam)            *
  343.  *                                        *
  344.  *  PURPOSE    : Dialog function File/SaveAs. It waits for a filename, and  *
  345.  *         then calls SaveFile or cancels the operation.            *
  346.  *                                        *
  347.  ****************************************************************************/
  348.  
  349. BOOL FAR PASCAL SaveAsDlgProc( hwnd, message, wParam, lParam)
  350. HWND hwnd;
  351. WORD message;
  352. WORD wParam;
  353. LONG lParam;
  354. {
  355.     char   sz[64];
  356.     char   *pch;
  357.     BOOL   fExt;
  358.     HWND   hwndSave;
  359.  
  360.     switch (message){
  361.  
  362.     case WM_INITDIALOG:
  363.  
  364.         /* Identify the window whose contents we're saving */
  365.         hwndSave = LOWORD (lParam);
  366.  
  367.         /* Set it's name in the property list */
  368.         SetProp (hwnd, PROP_FILENAME, hwndSave);
  369.  
  370.         GetWindowText (hwndSave, sz, sizeof(sz));
  371.  
  372.         /* Set the save from string... */
  373.         SetSaveFrom (hwnd,sz);
  374.  
  375.         /* Generate a filename complete with extension */
  376.         AnsiUpper (sz);
  377.         for (fExt = FALSE, pch = sz; *pch; pch++)
  378.         if (*pch == '.')
  379.             fExt = TRUE;
  380.         else if (*pch == '\\')
  381.             fExt = FALSE;
  382.         if (!fExt)
  383.         LoadString (hInst, IDS_ADDEXT, (LPSTR)pch, pch - sz);
  384.  
  385.         /* Display the filename in the edit control */
  386.         SetDlgItemText (hwnd, IDD_SAVETO, sz);
  387.  
  388.         /* Select the entire range of text */
  389.         SendDlgItemMessage (hwnd, IDD_SAVETO, EM_SETSEL, 0, MAKELONG (0,100));
  390.  
  391.         DlgDirList (hwnd, "*.*", IDD_DIRS, IDD_PATH, ATTR_DIRS);
  392.  
  393.         /* enable OK butto iff edit control is nonempty */
  394.         if (!*sz)
  395.         EnableWindow (GetDlgItem (hwnd, IDOK), FALSE);
  396.         break;
  397.  
  398.     case WM_COMMAND:
  399.         switch (wParam){
  400.         case IDCANCEL:
  401.             /* Abort operation */
  402.             EndDialog(hwnd,1);
  403.             break;
  404.  
  405.         case IDOK:
  406.            /*  Just change the title of the MDI child. The calling
  407.             *  function of ChangeFile(), which uses the title text
  408.             *  for the filename, will do the actual save.
  409.             */
  410.             hwndSave = GetProp (hwnd, PROP_FILENAME);
  411.             GetDlgItemText (hwnd, IDD_SAVETO, sz, sizeof(sz));
  412.             AnsiUpper ((LPSTR)sz);
  413.             SetWindowText (hwndSave, sz);
  414.             EndDialog (hwnd, 0);
  415.             break;
  416.  
  417.         case IDD_SAVETO:
  418.            /* If the edit control changes, check to see if its empty.
  419.             * enable OK if it contains something
  420.             */
  421.             if (HIWORD(lParam) != EN_CHANGE)
  422.             return FALSE;
  423.             EnableWindow (GetDlgItem (hwnd, IDOK),
  424.             (WORD) SendDlgItemMessage (hwnd,
  425.                            IDD_SAVETO,
  426.                            WM_GETTEXTLENGTH,
  427.                            0,
  428.                            0L));
  429.             break;
  430.  
  431.         case IDD_DIRS:
  432.             if (HIWORD(lParam)==LBN_DBLCLK){
  433.             char szT[64];
  434.  
  435.             DlgDirSelect ( hwnd, szT, IDD_DIRS);
  436.             lstrcat ( szT, "*.*");
  437.             DlgDirList (hwnd, szT, IDD_DIRS, IDD_PATH, ATTR_DIRS);
  438.             break;
  439.             }
  440.             return FALSE;
  441.  
  442.         default:
  443.             return FALSE;
  444.         }
  445.  
  446.     default:
  447.         return FALSE;
  448.     }
  449.     return TRUE;
  450. }
  451.  
  452. /****************************************************************************
  453.  *                                        *
  454.  *  FUNCTION   : ChangeFile (hwnd)                        *
  455.  *                                        *
  456.  *  PURPOSE    : Invokes the File/SaveAs dialog.                *
  457.  *                                        *
  458.  *  RETURNS    : TRUE  - if user selected OK or NO.                *
  459.  *         FALSE - otherwise.                        *
  460.  *                                        *
  461.  ****************************************************************************/
  462.  
  463. BOOL FAR PASCAL ChangeFile (hwnd)
  464. HWND hwnd;
  465. {
  466.     FARPROC lpfn;
  467.     int     i;
  468.  
  469.     lpfn = MakeProcInstance (SaveAsDlgProc, hInst);
  470.     i = DialogBoxParam (hInst, IDD_SAVEAS, hwnd, lpfn, MAKELONG (hwnd, 0));
  471.     FreeProcInstance (lpfn);
  472.     if (!i)
  473.     SetWindowWord (hwnd, GWW_UNTITLED, 0);
  474.     return !i;
  475. }
  476.